/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.cef.repository.dbcolumninfo;

import com.inspur.edp.cef.api.repository.ITypeTransProcesser;
import com.inspur.edp.cef.repository.adaptoritem.BaseAdaptorItem;
import com.inspur.edp.cef.repository.typetransprocesser.TypeTransProcessorFactory;
import com.inspur.edp.cef.repository.utils.StringUtil;
import com.inspur.edp.cef.spi.entity.info.propertyinfo.*;
import com.inspur.edp.cef.spi.entity.resourceInfo.builinImpls.CefEntityResInfoImpl;
import com.inspur.edp.cef.spi.jsonser.base.StringUtils;

import java.util.Map;

public final class ColumnInfoUtils {
  public static  void convertPropertyInfoToColumnInfo(DataTypePropertyInfo propertyInfo,
                                                      CefEntityResInfoImpl entityResInfo, BaseAdaptorItem adaptorItem) {
    if (propertyInfo.getObjectInfo() != null && propertyInfo
            .getObjectInfo() instanceof ComplexUdtPropertyInfo&&(propertyInfo.getDbColumnName()==null||propertyInfo.getDbColumnName().equals(""))) {
      ComplexUdtPropertyInfo complexUdtPropertyInfo = (ComplexUdtPropertyInfo) propertyInfo
              .getObjectInfo();

      if(propertyInfo.getDbColumnName()!=null&&"".equals(propertyInfo.getDbColumnName())==false)
      {
        DbColumnInfo dbColumnInfo = new DbColumnInfo(propertyInfo.getPropertyName(),
                propertyInfo.getDbColumnName(),
                propertyInfo.getDbDataType(), propertyInfo.getLength(), propertyInfo.getPrecision(),
                isPrimaryKey(propertyInfo, entityResInfo), false, propertyInfo.isMultiLaguange(),
                isParentId(propertyInfo, entityResInfo, adaptorItem), isUdtElement(propertyInfo),
                isAssociation(propertyInfo), isEnumElement(propertyInfo),
                propertyInfo.getPropertyName(), getTypeProcessor(propertyInfo));
        dbColumnInfo.setDataTypePropertyInfo(propertyInfo);
        adaptorItem
                .addColumn(dbColumnInfo);
      }
      else
      {
        for (Map.Entry<String, DataTypePropertyInfo> propertyInfoEntry : complexUdtPropertyInfo
                .getPropertyInfos().entrySet()) {
          DataTypePropertyInfo refDataTypePropertyInfo = propertyInfoEntry.getValue();
          ComplexUdtRefColumnInfo dbColumnInfo=new ComplexUdtRefColumnInfo(refDataTypePropertyInfo.getPropertyName(),
                  refDataTypePropertyInfo.getDbColumnName(),
                  refDataTypePropertyInfo.getDbDataType(), refDataTypePropertyInfo.getLength(), refDataTypePropertyInfo.getPrecision(),
                  isPrimaryKey(refDataTypePropertyInfo, entityResInfo), false, refDataTypePropertyInfo.isMultiLaguange(),
                  isParentId(refDataTypePropertyInfo, entityResInfo, adaptorItem), isUdtElement(refDataTypePropertyInfo),
                  isAssociation(refDataTypePropertyInfo), isEnumElement(refDataTypePropertyInfo),
                  propertyInfo.getPropertyName(), getTypeProcessor(refDataTypePropertyInfo));
          dbColumnInfo.setBelongUdtPropertyInfo(propertyInfo);
          dbColumnInfo.setDataTypePropertyInfo(refDataTypePropertyInfo);
          adaptorItem.addColumn(dbColumnInfo);
        }
      }
    }
    else if(propertyInfo.getObjectInfo()!=null&&propertyInfo.getObjectInfo() instanceof DynamicSetPropertyInfo)
      return;
    else if(propertyInfo.getDbColumnName()==null||"".equals(propertyInfo.getDbColumnName())){
      return;
    }
    else {
      DbColumnInfo dbColumnInfo=  new DbColumnInfo(propertyInfo.getPropertyName(),
              propertyInfo.getDbColumnName(),
              propertyInfo.getDbDataType(), propertyInfo.getLength(), propertyInfo.getPrecision(),
              isPrimaryKey(propertyInfo, entityResInfo), false, propertyInfo.isMultiLaguange(),
              isParentId(propertyInfo, entityResInfo, adaptorItem), isUdtElement(propertyInfo),
              isAssociation(propertyInfo), isEnumElement(propertyInfo),
              propertyInfo.getPropertyName(), getTypeProcessor(propertyInfo));
      dbColumnInfo.setDataTypePropertyInfo(propertyInfo);

      adaptorItem.addColumn(dbColumnInfo);
    }
  }

  /**
   * 获取虚拟DbColumnInfo
   * @param propertyInfo
   * @param entityResInfo
   * @return
   */
  private static DbColumnInfo getVirtualDbColumnInfo(DataTypePropertyInfo propertyInfo, CefEntityResInfoImpl entityResInfo){
    DbColumnInfo dbColumnInfo=  new DbColumnInfo(propertyInfo.getPropertyName(),
            propertyInfo.getDbColumnName(),
            propertyInfo.getDbDataType(), propertyInfo.getLength(), propertyInfo.getPrecision(),
            isPrimaryKey(propertyInfo, entityResInfo), false, propertyInfo.isMultiLaguange(),
            false, isUdtElement(propertyInfo),
            isAssociation(propertyInfo), isEnumElement(propertyInfo),
            propertyInfo.getPropertyName(), getTypeProcessor(propertyInfo));
    dbColumnInfo.setDataTypePropertyInfo(propertyInfo);
    if(propertyInfo.getFieldReposConfigInfo() != null && !StringUtils.isNullOrEmpty(propertyInfo.getFieldReposConfigInfo().getConfigImpl())){
      dbColumnInfo.setFieldReposExtendConfigClassImpl(propertyInfo.getFieldReposConfigInfo().getConfigImpl());
    }
    dbColumnInfo.setVirtual(true);
    return dbColumnInfo;
  }
  private static ITypeTransProcesser getTypeProcessor(DataTypePropertyInfo dataTypePropertyInfo) {
    return TypeTransProcessorFactory.getTypeTransProcessor(dataTypePropertyInfo);
  }

  private static boolean isEnumElement(DataTypePropertyInfo propertyInfo) {
    if(propertyInfo.getObjectInfo()==null)
      return false;
    if(propertyInfo.getObjectInfo() instanceof EnumPropertyInfo)
      return true;
    if(propertyInfo.getObjectInfo() instanceof SimpleEnumUdtPropertyInfo)
      return true;
    return false;
  }

  private static boolean isAssociation(DataTypePropertyInfo propertyInfo) {
    if(propertyInfo.getObjectInfo()==null)
      return false;
    if(propertyInfo.getObjectInfo() instanceof AssocationPropertyInfo)
      return true;
    if(propertyInfo.getObjectInfo() instanceof SimpleAssoUdtPropertyInfo)
      return true;
    return false;
  }

  private static boolean isUdtElement(DataTypePropertyInfo propertyInfo) {
    return propertyInfo.getObjectInfo()!=null&&propertyInfo.getObjectInfo() instanceof UdtPropertyInfo;
  }

  private static boolean isParentId(DataTypePropertyInfo propertyInfo,
                                    CefEntityResInfoImpl entityResInfo,
                                    BaseAdaptorItem adaptorItem) {
    if (propertyInfo.getPropertyName() == null || propertyInfo.getPropertyName().equals(""))
      return false;
    return propertyInfo.getPropertyName().equals(entityResInfo.getParentProprety());
  }

  private static boolean isPrimaryKey(DataTypePropertyInfo propertyInfo,CefEntityResInfoImpl entityResInfo) {
    return entityResInfo.getPrimaryKey().equals(propertyInfo.getPropertyName());
  }
}
